package com.itheima.d1_char_stream;

import java.io.FileReader;
import java.io.Reader;

/**
 * 目标：掌握文件字符输入流。
 *
 * FileReader（文件字符输入流）
 * 作用：以内存为基准，可以把文件中的数据以字符的形式读入到内存中去。
 *
 *字节流：
 *  适合复制文件等，不适合读写文本文件，因为容易出现乱码
 *  例如读取文本文件输出为例子：每次读取一个字节并输出，会导致截断汉字的字节导致乱码。每次读取多个字节，也可能会截断汉字字节。一次读完所有字节，受大小限制
 *字符流：
 *  适合读写文本文件内容
 *
 *
 *   *  IO流总体来看就有四大流
 *  *      字节输入流   抽象类 InputStream     实现类 FileInputStream
 *  *      字节输出流   抽象类 OutputStream    实现类 FileOutputSteam
 *  *      字符输入流   抽象类 Reader          实现类 FileReader
 *  *      字符输出流   抽象类 Writer          实现类 FileWriter
 *  *
 *  *总结流的四大类:
 *  * 字节输入流：以内存为基准，来自磁盘文件/网络中的数据以字节的形式读入到内存中去的流
 *  * 字节输出流：以内存为基准，把内存中的数据以字节写出到磁盘文件或者网络中去的流。
 *  * 字符输入流：以内存为基准，来自磁盘文件/网络中的数据以字符的形式读入到内存中去的流。
 *  * 字符输出流：以内存为基准，把内存中的数据以字符写出到磁盘文件或者网络介质中去的流。
 *
 *  I指Input，称为输入流：负责把数据读到内存中去
 *  O指Output，称为输出流：负责写数据出去到磁盘等
 *
 *          构造器                               说明
 *  public FileReader(File file)         创建字符输入流管道与源文件接通
 *  public FileReader(String pathname)   创建字符输入流管道与源文件接通
 *      方法名称
 *  public int read()                   每次读取一个字符返回，如果发现没有数据可读会返回-1
 *  public int read(char[] buffer)      每次用一个字符数组去读取数据，返回字符数组读取了多少个字符，如果发现没有数据可读会返回-1
 *
 *  我自己总结：和前面的文件字节输入输出流类似，只是改变了输入或者输出的单位，字节变成字符
 *
 * 疑惑：
 *   我也不懂，char只占两个字节，但是UTF-8中汉字占三个字节。所以UTF-8的汉字怎么塞得进char类型中去，不会因为读取字节不完整导致乱码？
 */
public class FileReaderTest1 {
    public static void main(String[] args)  {
        try (
                // 1、创建一个文件字符输入流管道与源文件接通
                //还是用try with catch的资源释放方式更加简单
                Reader fr = new FileReader("Day09Io-App2\\src\\itheima01.txt");     //也是多态的写法

                //自己试一试
                Reader zeng1 = new FileReader("Day08File-Io-App\\src\\itheima01.txt");
                Reader zeng2 = new FileReader("Day08File-Io-App\\src\\itheima02.txt");
                ){

            // 2、读取文本文件的内容了。
      /*      int c; // 记住每次读取的字符编号。
            while ((c = fr.read()) != -1){
                //不会乱码，弹幕：应该是字节流读的是字节,有一个字节,也有三个字节,字符流将一个字符看做一个单位,没有字节的区别了,a和啊是一个字符单位.
                System.out.print((char) c);
            }*/
            // 每次读取一个字符的形式，性能肯定是比较差的。


            // 3、每次读取多个字符。
            // 弹幕：他的意思是char只占两个字节，但是UTF-8中汉字占三个字节。所以UTF-8的汉字怎么塞得进插入类型中去
            //弹幕：char存放的是unicode码，不是utf-8编码方式。
            char[] buffer = new char[3];
            int len; // 记住每次读取了多少个字符。
            while ((len = fr.read(buffer)) != -1){
                // 读取多少倒出多少
                System.out.print(new String(buffer, 0, len));
            }
            // 性能是比较不错的！

            System.out.println();
            System.out.println("------------自己试一试，和前面的文件字节输入输出流类似，只是改变了输入输出的单位，字节变成字符----------");
            int zeng1Char1 = zeng1.read();
            System.out.println("调用read方法返回的东西： "+zeng1Char1);
            System.out.println("调用read方法返回的东西，强制转换为char类型： "+(char)zeng1Char1);

            System.out.println("-----------------------zeng1循环的进行文件字符输入流： ");
            int zeng11;
            while ((zeng11=zeng1.read())!=-1){
                System.out.print((char) zeng11);
            }


            System.out.println();
            System.out.println("-----------zeng2我要每次文件字符输出流好几个字符，字符数组------");
            char[] zeng2Char = new char[3];
            int zeng2Len ;
           /* //我的错误写法，但是没想到read方法还可以有这些形参，并且我写的是if判断。。。。
            if (zeng2.read()!=-1){
                System.out.println((char) zeng2.read(zeng2Char,0,zengLen));
            }*/
            while ((zeng2Len = zeng2.read(zeng2Char)) != -1){
                String zeng2s = new String(zeng2Char,0,zeng2Len);
                System.out.print(zeng2s);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
